package com.huxuesong.prcc.ums.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huxuesong.prcc.dto.UmsMemberDTO;
import com.huxuesong.prcc.dto.UmsMemberTransferInfoDTO;
import com.huxuesong.prcc.dto.dtomapper.UmsMemberDTOMapper;
import com.huxuesong.prcc.dto.dtomapper.UmsMemberTransferInfoDTOMapper;
import com.huxuesong.prcc.sys.entity.SysSetting;
import com.huxuesong.prcc.sys.mapper.SysSettingMapper;
import com.huxuesong.prcc.ums.entity.UmsMemberTransferInfo;
import com.huxuesong.prcc.ums.mapper.UmsCoinAddressMapper;
import com.huxuesong.prcc.ums.entity.UmsCoinAddress;
import com.huxuesong.prcc.ums.entity.UmsMember;
import com.huxuesong.prcc.ums.mapper.UmsMemberMapper;
import com.huxuesong.prcc.ums.mapper.UmsMemberTransferInfoMapper;
import com.huxuesong.prcc.ums.service.IUmsMemberService;
import com.huxuesong.prcc.ums.service.RedisService;
import com.huxuesong.prcc.util.*;
import com.huxuesong.prcc.util.submail.SubMailSender;
import com.huxuesong.prcc.vo.MemberDetails;
import com.mysql.cj.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.klock.annotation.Klock;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.sql.Date;
import java.sql.Time;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;
import java.util.concurrent.CompletableFuture;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author hxs
 * @since 2019-08-02
 */
@Service
@Slf4j
public class UmsMemberServiceImpl extends ServiceImpl<UmsMemberMapper, UmsMember> implements IUmsMemberService {

    @Resource
    private UmsMemberMapper memberMapper;

    @Resource
    private UmsCoinAddressMapper umsCoinAddressMapper;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private RedisService redisService;

    @Autowired
    private SubMailSender subMailSender;

    @Autowired
    private UmsMemberTransferInfoMapper umsMemberTransferInfoMapper;

    @Autowired
    private SysSettingMapper sysSettingMapper;

    @Value("${redis.key.prefix.authCode}")
    private String REDIS_KEY_PREFIX_AUTH_CODE;
    @Value("${authCode.expire.seconds}")
    private Long AUTH_CODE_EXPIRE_SECONDS;
    @Value("${jwt.tokenHead}")
    private String tokenHead;


    @Override
    public UmsMember getCurrentMember() {
        try {
            SecurityContext ctx = SecurityContextHolder.getContext();
            Authentication auth = ctx.getAuthentication();
            MemberDetails memberDetails = (MemberDetails) auth.getPrincipal();
            return memberDetails.getUmsMember();
        } catch (Exception e) {
            return new UmsMember();
        }
    }

    @Override
    public UmsMember getByUsername(String username) {
        UmsMember umsMember = new UmsMember();
        umsMember.setUsername(username);

        UmsCoinAddress coinAddress = umsCoinAddressMapper.selectOne(new QueryWrapper<UmsCoinAddress>()
                .eq("username",username));
        umsMember = memberMapper.selectOne(new QueryWrapper<>(umsMember));

        if (umsMember != null) {
            if (coinAddress != null){
                umsMember.setCoinAddress(coinAddress.getCoinAddress());
            }
        }

        return umsMember;
    }

    @Override
    public CommonResult login(String username, String password){
        Map<String, Object> tokenMap = new HashMap<>();
        String token = null;
        try {
            UserDetails userDetails = userDetailsService.loadUserByUsername(username);
            if (!passwordEncoder.matches(password, userDetails.getPassword())) {
                return new CommonResult().validateFailed("用户名或密码错误");
            }
            UmsMember member = this.getByUsername(username);
            //验证验证码
           /* if (!verifyAuthCode(user.getCode(), member.getPhone())) {
                throw  new ApiMallPlusException("验证码错误");
            }*/

            //   Authentication authentication = authenticationManager.authenticate(authenticationToken);
            Authentication authentication = new UsernamePasswordAuthenticationToken(
                    userDetails, null, userDetails.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(authentication);
            token = jwtTokenUtil.generateToken(userDetails);
            tokenMap.put("userInfo", member);
        } catch (AuthenticationException e) {
            log.warn("登录异常:{}", e.getMessage());
            return new CommonResult().validateFailed("用户名或密码错误");

        }
        tokenMap.put("token", token);
        tokenMap.put("tokenHead", tokenHead);

        return new CommonResult().success(tokenMap);
    }

    @Override
    @Transactional
    public CommonResult register(UmsMemberDTO umsMemberDTO) {

        log.info("get register info "+umsMemberDTO);
        if(umsMemberDTO.getUsername()==null || !PhoneUtil.checkPhone(umsMemberDTO.getUsername())){
            return new CommonResult().validateFailed("请输入合法手机号");
        }

        //验证验证码
        if (!verifyAuthCode(umsMemberDTO.getAuthcode(), umsMemberDTO.getUsername())) {
            return new CommonResult().failed("验证码错误");
        }


        if (StringUtils.isNullOrEmpty(umsMemberDTO.getPassword()) || !umsMemberDTO.getPassword().equals(umsMemberDTO.getConfimpassword())){
            return new CommonResult().failed("密码不一致");
        }
        UmsMember member = UmsMemberDTOMapper.MAPPER.toUmsMember(umsMemberDTO);
        // 20190611 必须有邀请码才能注册

        if(StringUtils.isNullOrEmpty(umsMemberDTO.getInvitedCode())){
            return new CommonResult().failed("请填写邀请码");
        }

//        if(StringUtils.isNullOrEmpty(umsMemberDTO.getInviteCode())){
////            return new CommonResult().failed("请填写邀请码");
//        }
//        else{
//            member.setInvitedUserId(ShareCodeUtils.codeToId(umsMemberDTO.getInviteCode()).intValue());
//            UmsMember invitedUser =  memberMapper.selectById(member.getInvitedUserId());
//            if (invitedUser == null){
//                return new CommonResult().failed("邀请码不存在");
//            }else {
//                invitedUser.setFans(invitedUser.getFans()+1);
//                memberMapper.updateById(invitedUser);
//                member.setInvitedUserName(invitedUser.getUsername());
//            }
//>>>>>>> fix bug

        member.setInvitedUserId(ShareCodeUtils.codeToId(umsMemberDTO.getInviteCode()).intValue());
        UmsMember invitedUser =  memberMapper.selectById(member.getInvitedUserId());
        if (invitedUser == null){
            return new CommonResult().failed("邀请码不存在");
        }else {
            invitedUser.setFans(invitedUser.getFans()+1);
            memberMapper.updateById(invitedUser);
            member.setInvitedUserName(invitedUser.getUsername());
        }

        log.info("UmsMemberDTOMapper to umsMember"+member);
        member.setPassword(passwordEncoder.encode(member.getPassword()));

        QueryWrapper<UmsMember> qryWrapper = new QueryWrapper<>();
        qryWrapper.eq("username",member.getUsername());
        UmsMember existMember = memberMapper.selectOne(qryWrapper);

        if (existMember != null){
            return new CommonResult().failed("您已经注册");
        }


        if (memberMapper.insert(member) == 0){
            return new CommonResult().failed("网络错误");

        }else {
            member.setInvitedCode(ShareCodeUtils.idToCode(member.getId().longValue()));

            List<UmsCoinAddress> coinAddresses = umsCoinAddressMapper.selectList(new QueryWrapper<UmsCoinAddress>()
                    .lambda()
                    .eq(UmsCoinAddress::getUsername, "")
                    .last("limit 1"));
            if (coinAddresses.size() == 0){
                return new CommonResult().failed("没有可用地址");
            }

            UmsCoinAddress coinAddress = coinAddresses.get(0);
            member.setCoinAddress(coinAddresses.get(0).getCoinAddress());

            memberMapper.updateById(member);
            member = memberMapper.selectById(member.getId());


            return new CommonResult().success("注册成功",member);
        }


    }

    @Override
    public CommonResult generateAuthCode(String phone) {

        StringBuilder sb = new StringBuilder();
        Random random = new Random();

        for (int i = 0; i < 6; i++) {
            sb.append(random.nextInt(10));
        }


        if (!StringUtils.isNullOrEmpty(phone) && PhoneUtil.checkPhone(phone)){
            log.info(phone+"get authcode :"+sb.toString());
            CompletableFuture.runAsync(()->{
                subMailSender.sendMsgAuthCode(phone,"【PRCC】您好，您的验证码是:"+sb.toString());

            });


        }else{
            return new CommonResult().failed("请输入正确手机号码");
        }

        //验证码绑定手机号并存储到redis
        redisService.set(REDIS_KEY_PREFIX_AUTH_CODE + phone, sb.toString());
        redisService.expire(REDIS_KEY_PREFIX_AUTH_CODE + phone, AUTH_CODE_EXPIRE_SECONDS);
        return new CommonResult().success("获取验证码成功","");
    }

    @Override
    public CommonResult updatePassword(UmsMemberDTO memberDTO) {
        if(!PhoneUtil.checkPhone(memberDTO.getUsername())){
            log.error("updatePassword username is error" + memberDTO.getUsername());
            return new CommonResult().failed("请输入合法手机号");
        }

        if(StringUtils.isNullOrEmpty(memberDTO.getPassword())){
            return new CommonResult().failed("密码不能为空");
        }

        if (!memberDTO.getPassword().equals(memberDTO.getConfimpassword())){
            return new CommonResult().failed("密码不一致");
        }
        QueryWrapper<UmsMember> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username",memberDTO.getUsername());

        UmsMember currentUser = memberMapper.selectOne(queryWrapper);

        if (currentUser == null){
            return new CommonResult().failed("用户不存在");
        }
        //验证验证码
        if (!verifyAuthCode(memberDTO.getAuthcode(), memberDTO.getUsername())) {
            return new CommonResult().failed("验证码错误");
        }

        currentUser.setPassword(passwordEncoder.encode(memberDTO.getPassword()));
        memberMapper.updateById(currentUser);
        return new CommonResult().success("密码修改成功", currentUser);
    }

    //对输入的验证码进行校验
    private boolean verifyAuthCode(String authCode, String username) {
        if (org.springframework.util.StringUtils.isEmpty(authCode)) {
            return false;
        }
        String phoneAuthCode = redisService.get(REDIS_KEY_PREFIX_AUTH_CODE + username);

        return authCode.equals(phoneAuthCode);
    }

    @Override
    public String refreshToken(String oldToken) {
        String token = oldToken.substring(tokenHead.length());
        if (jwtTokenUtil.canRefresh(token)) {
            return jwtTokenUtil.refreshToken(token);
        }
        return null;
    }

    @Override
    @Transactional
    public CommonResult createCoinAddress() {
        UmsMember member = this.getCurrentMember();
        if(!StringUtils.isNullOrEmpty(member.getCoinAddress())){
            return new CommonResult().failed("该账号已申请过");
        }

        List<UmsCoinAddress> coinAddresses = umsCoinAddressMapper.selectList(new QueryWrapper<UmsCoinAddress>()
                .lambda()
                .eq(UmsCoinAddress::getUsername, "")
                .last("limit 1"));
        if (coinAddresses.size() == 0){
            return new CommonResult().failed("没有可用地址");
        }

        UmsCoinAddress coinAddress = coinAddresses.get(0);
        member.setCoinAddress(coinAddresses.get(0).getCoinAddress());
        memberMapper.updateById(member);

        coinAddress.setUsername(member.getUsername());
        umsCoinAddressMapper.updateById(coinAddress);



        return new CommonResult().success("申请地址成功",member);
    }

    @Override
    @Transactional
    public CommonResult transfer(UmsMemberTransferInfoDTO transferInfoDTO) {

        // PRCC 兑换 s令牌 兑换比例 10：1
        UmsMember member = this.getCurrentMember();
        UmsMemberTransferInfo transferInfo = UmsMemberTransferInfoDTOMapper.MAPPER.toUmsMemberTransferInfo(transferInfoDTO);
        transferInfo.setBeginTime(LocalDateTime.now(ZoneOffset.of("+8")));
        transferInfo.setEndTime(LocalDateTime.now(ZoneOffset.of("+8")));
        transferInfo.setTransferType(transferInfoDTO.getType());
        transferInfo.setUserName(member.getUsername());
        transferInfo.setTransferType(transferInfoDTO.getType());
        SysSetting setting = sysSettingMapper.selectById(1);
        //prcc 兑换s token
        if (transferInfoDTO.getType() == UmsMemberTransferInfoDTO.EXCHANGE_PRCC_STOEKN){
           if (transferInfo.getPrcc().intValue()>=0){
//               return new CommonResult().failed("prcc参数值不能大于或等于0");
               transferInfo.setPrcc(transferInfo.getPrcc().multiply(new BigDecimal(-1)));
           }
           if (transferInfo.getPrcc().intValue()%setting.getStokenToPrcc() != 0){
               return new CommonResult().failed("请输入"+setting.getStokenToPrcc()+"的整数倍");
           }
           if (transferInfo.getPrcc().add(member.getPrcc()).doubleValue()<0){
               return new CommonResult().failed("prcc余额不足");
           }
           transferInfo.setTransferDesc(UmsMemberTransferInfoDTO.EXCHANGE_PRCC_STOKEN_STR);
           transferInfo.setSToken(transferInfo.getPrcc().multiply(new BigDecimal(-0.1)));
           member.setPrcc(member.getPrcc().add(transferInfo.getPrcc()));
           member.setSToken(member.getSToken().add(transferInfo.getSToken()));

        }
        // s令牌兑换PRCC  兑换比例 1：10
        else if(transferInfoDTO.getType() == UmsMemberTransferInfoDTO.EXCHANGE_STOEKN_PRCC){
            if (transferInfo.getSToken().doubleValue()>=0){
                transferInfo.setSToken(transferInfo.getSToken().multiply(new BigDecimal(-1)));
            }

            if(transferInfo.getSToken().add(member.getSToken()).doubleValue()<0){
                return new CommonResult().failed("s令牌余额不足");
            }
            transferInfo.setTransferDesc(UmsMemberTransferInfoDTO.EXCHANGE_STOKEN_PRCC_STR);
            transferInfo.setPrcc(transferInfo.getSToken().multiply(new BigDecimal(-10)));
            member.setPrcc(member.getPrcc().add(transferInfo.getPrcc()));
            member.setSToken(member.getSToken().add(transferInfo.getSToken()));
        }
        else if(transferInfoDTO.getType() == UmsMemberTransferInfoDTO.EXCHANGE_YUANBAO_PRCC){
             if(member.getYuanbao().intValue()<2000){
                 return new CommonResult().failed("余额低于2000，不能兑换");
             }

             if(member.getSToken().intValue()< 10){
                return new CommonResult().failed("s令牌低于"+ 10+",禁止兑换");
             }

             member.setYuanbao(member.getYuanbao().subtract(new BigDecimal(2000)));
             member.setPrcc(member.getPrcc().add(new BigDecimal(2000)));
             member.setSToken(member.getSToken().subtract(new BigDecimal(10)));

            transferInfo.setTransferDesc(UmsMemberTransferInfoDTO.EXCHANGE_YUANBAO_PRCC_STR);
            transferInfo.setYuanbao(new BigDecimal(-2000));
            transferInfo.setPrcc(new BigDecimal(2000));
            transferInfo.setSToken(new BigDecimal(-10));



        }else if(transferInfoDTO.getType() == UmsMemberTransferInfoDTO.UNLOCK_PRCC){
            int[] amountTypeArr = new int[]{2000,5000,10000,20000,100000};
//            int[] sTokenArr = new int[]{10,25,50,100,500};

            if(transferInfoDTO.getAmountType()<0 || transferInfoDTO.getAmountType()>= amountTypeArr.length){
                return new CommonResult().failed("type值有误");
            }

            if(member.getPrccLock().intValue()<amountTypeArr[transferInfoDTO.getAmountType()]){
                return new CommonResult().failed("当前锁定的PRCC低于"+amountTypeArr[transferInfoDTO.getAmountType()]);
            }

            // 兑换大约2000 要满足规则才能进行兑换
            if(transferInfo.getTransferType()>0){
                List<UmsMemberTransferInfo> transferInfos = umsMemberTransferInfoMapper.selectList(
                        new QueryWrapper<UmsMemberTransferInfo>()
                                .lambda()
                                .eq(UmsMemberTransferInfo::getUserName,member.getUsername())
                                .eq(UmsMemberTransferInfo::getTransferType,transferInfoDTO.getType())
                                .eq(UmsMemberTransferInfo::getPrccLock,new BigDecimal(-1*amountTypeArr[transferInfo.getTransferType()-1]))

                );

                if (transferInfos.size()<5){
                    return new CommonResult().failed("兑换条件不满足要求");
                }

            }



            member.setPrccLock(member.getPrccLock().subtract(new BigDecimal(amountTypeArr[transferInfoDTO.getAmountType()])));

            transferInfo.setTransferDesc(UmsMemberTransferInfoDTO.UNLOCK_PRCC_STR);
            transferInfo.setPrccLock(new BigDecimal(amountTypeArr[transferInfoDTO.getAmountType()]).multiply(new BigDecimal(-1)));
            transferInfo.setYuanbao(new BigDecimal(amountTypeArr[transferInfoDTO.getAmountType()]*1.2));
            transferInfo.setTreePrcc(new BigDecimal(amountTypeArr[transferInfoDTO.getAmountType()]*3));
            transferInfo.setEndTime(null);
            transferInfo.setStatus(0);
            transferInfo.setResMsg("兑换中");
        }
        else{
            return new CommonResult().failed("type参数不合法");
        }

        umsMemberTransferInfoMapper.insert(transferInfo);
        memberMapper.updateById(member);
        return new CommonResult().success("成功");
    }

    @Override
    public CommonResult transferDetail(Integer type, Integer pageNum, Integer pageSize) {
        UmsMember member = this.getCurrentMember();
        log.info("transferDetail  type:"+type+" pageNum:"+pageNum+"  pageSize:"+pageSize);

        // 查询所有的
        if (type.equals(UmsMemberTransferInfoDTO.TRANSFER_TYPE_ALL)){
            IPage<UmsMemberTransferInfo> transferInfoPage = umsMemberTransferInfoMapper.selectPage(new Page<>(pageNum,pageSize),
                    new QueryWrapper<UmsMemberTransferInfo>()
                            .lambda()
                            .eq(UmsMemberTransferInfo::getUserName,member.getUsername()));
            return new CommonResult().success("查询",transferInfoPage);
        }
        // 查询所有兑换
        else if(type.equals(UmsMemberTransferInfoDTO.TRANSFER_TYPE_EXCHANGE)){
            IPage<UmsMemberTransferInfo> transferInfoPage = umsMemberTransferInfoMapper.selectPage(new Page<>(pageNum,pageSize),
                    new QueryWrapper<UmsMemberTransferInfo>()
                            .lambda()
                     .eq(UmsMemberTransferInfo::getUserName,member.getUsername())
                     .in(UmsMemberTransferInfo::getTransferType,UmsMemberTransferInfoDTO.TRANSFER_TYPE_EXCHANGE_LIST));
            return new CommonResult().success("查询",transferInfoPage);
        }
        // 查询所有的 提现
        else if(type.equals(UmsMemberTransferInfoDTO.TRANSFER_TYPE_OUT)){
            IPage<UmsMemberTransferInfo> transferInfoPage = umsMemberTransferInfoMapper.selectPage(new Page<>(pageNum,pageSize),
                    new QueryWrapper<UmsMemberTransferInfo>()
                            .lambda()
                            .eq(UmsMemberTransferInfo::getUserName,member.getUsername())
                            .in(UmsMemberTransferInfo::getTransferType,UmsMemberTransferInfoDTO.TRANSFER_TYPE_OUT_LIST));
            return new CommonResult().success("查询",transferInfoPage);
        }
        // 查询所有的 入账
        else if(type.equals(UmsMemberTransferInfoDTO.TRANSFER_TYPE_IN)){
            IPage<UmsMemberTransferInfo> transferInfoPage = umsMemberTransferInfoMapper.selectPage(new Page<>(pageNum,pageSize),
                    new QueryWrapper<UmsMemberTransferInfo>()
                            .lambda()
                            .eq(UmsMemberTransferInfo::getUserName,member.getUsername())
                            .in(UmsMemberTransferInfo::getTransferType,UmsMemberTransferInfoDTO.TRANSFER_TYPE_IN_LIST));
            return new CommonResult().success("查询",transferInfoPage);
        }

        else  if(type.equals(UmsMemberTransferInfoDTO.TRANSFER_TYPE_UNLOCKPRCC)){
            IPage<UmsMemberTransferInfo> transferInfoPage = umsMemberTransferInfoMapper.selectPage(new Page<>(pageNum,pageSize),
                    new QueryWrapper<UmsMemberTransferInfo>()
                            .lambda()
                            .eq(UmsMemberTransferInfo::getUserName,member.getUsername())
                            .eq(UmsMemberTransferInfo::getTransferType,24));
            return new CommonResult().success("查询",transferInfoPage);
        }

        else  if(type.equals(UmsMemberTransferInfoDTO.TRANSFER_TYPE_OTHER)){
            IPage<UmsMemberTransferInfo> transferInfoPage = umsMemberTransferInfoMapper.selectPage(new Page<>(pageNum,pageSize),
                    new QueryWrapper<UmsMemberTransferInfo>()
                            .lambda()
                            .eq(UmsMemberTransferInfo::getUserName,member.getUsername())
                            .eq(UmsMemberTransferInfo::getTransferType,UmsMemberTransferInfoDTO.TRANSFER_TYPE_OTHER_LIST));
            return new CommonResult().success("查询",transferInfoPage);
        }
        return new CommonResult().failed("type值错误");
    }

    @Override
    @Klock(keys={"#member.username"})
    @Transactional
    public CommonResult buyTree(UmsMember member) {
        if (member.getIsTreeActive() == 1){
            return new CommonResult().failed("您已购买摇钱树，请勿再次购买");
        }

        SysSetting setting = sysSettingMapper.selectById(1);

        if (setting == null || setting.getTreeCostPrcc()==null){
            return new CommonResult().failed("摇钱树价格配置错误，请联系管理员");
        }

        if (member.getPrcc().compareTo(setting.getTreeCostPrcc())<0){
            return new CommonResult().failed("PRCC余额不足");
        }
        // 购买成功后，赠送3w tree_prcc
        SysSetting setting1 = sysSettingMapper.selectById(1);
        member.setIsTreeActive(1);
        member.setPrcc(member.getPrcc().subtract(setting.getTreeCostPrcc()));
        member.setTreePrcc(new BigDecimal(setting1.getTreeIniPrccLock()));
        memberMapper.updateById(member);


        UmsMemberTransferInfo transferInfo = new UmsMemberTransferInfo();
        transferInfo.setUserName(member.getUsername());
        transferInfo.setBeginTime(LocalDateTime.now(ZoneOffset.of("+8")));
        transferInfo.setEndTime(LocalDateTime.now(ZoneOffset.of("+8")));
        transferInfo.setTreePrcc(new BigDecimal(setting1.getTreeIniPrccLock()));
        transferInfo.setPrcc(setting.getTreeCostPrcc().multiply(new BigDecimal(-1)));
        transferInfo.setTransferType(UmsMemberTransferInfoDTO.SHOCK_TREE_INIT_PRCC_LOCK);
        transferInfo.setTransferDesc(UmsMemberTransferInfoDTO.SHOCK_TREE_INIT_PRCC_LOCK_STR);
        umsMemberTransferInfoMapper.insert(transferInfo);


        if(!StringUtils.isNullOrEmpty(member.getInvitedUserName())){
            UmsMember invitedUser = this.getByUsername(member.getInvitedUserName());
            if (invitedUser!= null){
                invitedUser.setPrcc(invitedUser.getPrcc().add(setting1.getTreeCostPrcc().multiply(new BigDecimal(0.9))));
                transferInfo.setUserName(invitedUser.getUsername());
                transferInfo.setPrcc(setting1.getTreeCostPrcc().multiply(new BigDecimal(0.9)));
                transferInfo.setTransferType(UmsMemberTransferInfoDTO.TUIJIAN_TREE_PRCC);
                transferInfo.setTransferId(null);
                transferInfo.setTransferDesc(UmsMemberTransferInfoDTO.TUIJIAN_TREE_PRCC_STR);
                umsMemberTransferInfoMapper.insert(transferInfo);
                memberMapper.updateById(invitedUser);

            }


        }


        return new CommonResult().success(member);
    }

    @Override
    @Transactional
    // prcc_lock += tree_prcc*0.01  tree_prcc = tree_prcc*0.99
    public CommonResult shockTree(UmsMember member) {
        List<UmsMemberTransferInfo> umsMemberTransferInfos = umsMemberTransferInfoMapper.selectList(
          new QueryWrapper<UmsMemberTransferInfo>()
                  .eq("user_name",member.getUsername())
                  .eq("transfer_type",UmsMemberTransferInfoDTO.SHOCK_TREE_PRCC)
                  .between("begin_time", DateUtils.getTodayStartTime(),DateUtils.getTodayEndTime())
        );

        if (umsMemberTransferInfos.size() != 0){
            return new CommonResult().failed("今日摇一摇已达上限");
        }

        if(member.getTreePrcc().doubleValue() <=0){
            return new CommonResult().failed("暂无可解锁的PRCC");
        }

        SysSetting setting = sysSettingMapper.selectById(1);
        UmsMemberTransferInfo transferInfo = new UmsMemberTransferInfo();
        transferInfo.setUserName(member.getUsername());
        transferInfo.setBeginTime(LocalDateTime.now(ZoneOffset.of("+8")));
        transferInfo.setTreePrcc(member.getTreePrcc().multiply(new BigDecimal(-0.01)));
        transferInfo.setPrccLock(member.getTreePrcc().multiply(new BigDecimal(0.01)));

        transferInfo.setTransferType(UmsMemberTransferInfoDTO.SHOCK_TREE_PRCC);
        transferInfo.setTransferDesc(UmsMemberTransferInfoDTO.SHOCK_TREE_PRCC_STR);
        umsMemberTransferInfoMapper.insert(transferInfo);

        member.setTreePrcc(member.getTreePrcc().add(transferInfo.getTreePrcc()));
        member.setPrccLock(member.getPrccLock().add(transferInfo.getPrccLock()));
        memberMapper.updateById(member);
        return new CommonResult().success(member);
    }


    @Override
    public UmsMember getById(Long id) {
        return memberMapper.selectById(id);
    }

    @Override
    public CommonResult canceltransfer(UmsMember member,Integer transferId){
        UmsMemberTransferInfo transferInfo = umsMemberTransferInfoMapper.selectById(transferId);
        if (transferInfo == null){
            return new CommonResult().failed("id错误");
        }

        if(!transferInfo.getUserName().equals(member.getUsername())){
            return new CommonResult().failed("您无权取消！");
        }

        if(transferInfo.getStatus().equals(1)){
            return new CommonResult().failed("该转账已完成,无法进行取消!");
        }


        //取消  解锁锁定的prcc
        if(transferInfo.getTransferType().equals(UmsMemberTransferInfoDTO.UNLOCK_PRCC)){

            transferInfo.setStatus(2);
            transferInfo.setResMsg("已取消");

            member.setPrccLock(member.getPrccLock().subtract(transferInfo.getPrccLock()));

            memberMapper.updateById(member);
            umsMemberTransferInfoMapper.updateById(transferInfo);

            return new CommonResult().success("取消成功",member);

        }

//        //取消  提现prcc
//        if(transferInfo.getTransferType().equals(UmsMemberTransferInfoDTO.INNER_TRANSFER_PRCC)){
//
//            transferInfo.setStatus(2);
//            transferInfo.setResMsg("已取消");
//
//            member.setPrcc(member.getPrcc().subtract(transferInfo.getPrcc()));
//            memberMapper.updateById(member);
//            umsMemberTransferInfoMapper.updateById(transferInfo);
//            return new CommonResult().success("取消成功",member);
//
//        }
        return new CommonResult().failed("不允许取消");

    }

    @Override
    @Transactional
    public CommonResult withdrawprcc(UmsMember member, BigDecimal prcc, String recvCoinAddress) {

        if(prcc == null || recvCoinAddress == null){
            return new CommonResult().failed("参数不能为空");
        }

        if(prcc.doubleValue() == 0){
            return new CommonResult().failed("值不能为0");
        }

        if(prcc.doubleValue()>0){
            prcc = prcc.multiply(new BigDecimal(-1));
        }

        member.setPrcc(member.getPrcc().add(prcc));
        member.setPrccDongjie(member.getPrccDongjie().add(prcc.multiply(new BigDecimal(-1))));
        memberMapper.updateById(member);


        UmsMemberTransferInfo transferInfo = new UmsMemberTransferInfo();
        transferInfo.setUserName(member.getUsername());
        transferInfo.setBeginTime(LocalDateTime.now(ZoneOffset.of("+8")));
        transferInfo.setTreePrcc(prcc);
        transferInfo.setPrccDongjie(prcc.multiply(new BigDecimal(-1)));
        transferInfo.setPrcc(prcc);



        transferInfo.setTransferType(UmsMemberTransferInfoDTO.INNER_TRANSFER_PRCC);
        transferInfo.setTransferDesc(UmsMemberTransferInfoDTO.INNER_TRANSFER_PRCC_STR);

        transferInfo.setStatus(0);
        transferInfo.setResMsg("提现中");
        umsMemberTransferInfoMapper.insert(transferInfo);


        if(!StringUtils.isNullOrEmpty(member.getInvitedUserName())){
            UmsMember invitedUser = this.getByUsername(member.getInvitedUserName());
            if (invitedUser!= null){
                invitedUser.setSToken(invitedUser.getSToken().add(new BigDecimal(3)));
                transferInfo.setUserName(invitedUser.getUsername());
                transferInfo.setSToken(new BigDecimal(3));
                transferInfo.setTransferType(UmsMemberTransferInfoDTO.TUIJIAN_WITHDRAW_PRCC);
                transferInfo.setTransferId(null);
                transferInfo.setTransferDesc(UmsMemberTransferInfoDTO.TUIJIAN_WITHDRAW_PRCC_STR);
                umsMemberTransferInfoMapper.insert(transferInfo);
                memberMapper.updateById(invitedUser);
            }


        }

        return new CommonResult().success("提现成功");

    }

    @Override
    public CommonResult getSysSetting() {
        SysSetting setting = sysSettingMapper.selectById(1);
        return new CommonResult().success(setting);
    }
}
